home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / portfoli / bootst11.lzh / PF BOOTSTRAP VATIPX PPAGEC < prev    next >
Text File  |  1989-05-14  |  6KB  |  290 lines

  1. #ifndef lint
  2. static char *sccsid = "@(#)page.c    1.4    MS/ACF    89/05/08";
  3. #endif
  4.  
  5. /*
  6.  *    tip/page.c    (Douglas Kingston, Morgan Stanley & Co.)
  7.  *
  8.  *    This file contains code to send alphanumeric pages via
  9.  *    dialup paging services that support "Remote Entry Device
  10.  *    Protocol" (aka "IXO").  These services typically send to
  11.  *    devices like the Motorola PMR-2000 pager.
  12.  *
  13.  *    This module is designed to use the ACK/NAK packet protocol
  14.  *    to ensure the highest likelyhood of correct delivery of the
  15.  *    message.  The packets are checksummed and all messages are
  16.  *    acknowledged by the receiver.
  17.  *
  18.  *    To use this facility, tip must be called with the -p option,
  19.  *    a system name (what system to dial up) and finally a data
  20.  *    string which contains 3 items:  A login code/password, a list
  21.  *    pager id's to receive the message, and the message text.
  22.  *    The three fields are separated by tabs.  The pager id field
  23.  *    is further subdivided into a list of pager ids by commas.
  24.  *
  25.  *    For example:
  26.  *    tip -p metro "12345678\t20001,20002\tPlease call the office."
  27.  *
  28.  *    Would call the system called "metro" as listed in /etc/remote
  29.  *    and login with the ID 12345678.  The message "Please call
  30.  *    the office." would be sent to pagers 20001 and 20002.
  31.  *
  32.  *    This code has been tested only on the Metromedia Paging Services
  33.  *    system around New York City, though it should work on other
  34.  *    similiar systems.
  35.  *
  36.  *    Douglas Kingston
  37.  *    Morgan Stanley & Co. (19th Floor)
  38.  *    1251 Avenue of the Americas
  39.  *    NY, NY, 10020
  40.  */
  41.  
  42. #include <stdio.h>
  43. #include <ctype.h>
  44. #include <signal.h>
  45. #include <sys/time.h>
  46. #include "tip.h"
  47.  
  48. #define STX    002
  49. #define    ETX    003
  50. #define    EOT    004
  51. #define    ACK    006
  52. #define    NAK    025
  53. #define    ETB    027
  54. #define    ESC    033
  55. #define    RS    036
  56.  
  57. extern int vflag, FD;
  58. extern jmp_buf    jmpbuf;
  59.  
  60. extern char *strchr();
  61. extern int recvtimeout();
  62.  
  63. char    inbuf[270];
  64. char    mbuf[32];
  65. char    packet[270];
  66.  
  67. static char *addstr();
  68.  
  69. sendpage(data)
  70. char *data;
  71. {
  72.     int ret = 1;
  73.     int trys, i;
  74.     char *cp, *pager, *message;
  75.  
  76.     if (boolean(value(VERBOSE)))
  77.         vflag++;
  78.     if (vflag)
  79.         fputs("[Connected]\n", stderr);
  80.  
  81.     cp = data;
  82.     if (pager = strchr(data, '\t')) {
  83.         *pager = 0;
  84.         pager++;
  85.     } else {
  86.         fprintf(stderr, "Bad paging data: '%s'\n", data);
  87.         return(1);
  88.     }
  89.  
  90.     trys = 0;
  91.     do {
  92.         if (trys++ > 3) {
  93.             fprintf(stderr, "ID= retries failed\n");
  94.             goto done;
  95.         }
  96.         if (pgsend("\r"))
  97.             return(1);
  98.     } while (pgrecv("ID=", 5) < 3);
  99.  
  100.     trys = 0;
  101. login_again:
  102.  
  103.     if (pgsend("\033") || pgsend(cp) || pgsend("\r"))
  104.         return(1);
  105.  
  106.     /* Wait for ACK, NAK, EOT or Ready(?) */
  107.     if (pgrecv("\r", 10) <= 0) {
  108.         fprintf(stderr, "login timeout\n");
  109.         goto done;
  110.     }
  111.     switch(inbuf[0]) {
  112.     default:    if (trys++ < 4) goto login_again; else goto done;
  113.     case ACK:    break;
  114.     case NAK:    if (trys++ < 4) goto login_again; else goto done;
  115.     case RS:    fprintf(stderr, "login got RS\n"); goto done;
  116.     case ESC:
  117.         switch(inbuf[1]) {
  118.         case EOT:    goto done;
  119.         case '[':    if(inbuf[2] == 'p') break;
  120.         default:    fprintf(stderr, "got unknown ESC code\n");
  121.                 goto login_again;
  122.         }
  123.     }
  124.     pgrecv("\r", 10);    /* Swallow Go Ahead <ESC>[p */
  125.  
  126.     if (message = strchr(pager, '\t')) {
  127.         *message = 0;
  128.         message++;
  129.     } else
  130.         message = "[Message not specified]";
  131. next_pager:
  132.     if (cp = strchr(pager, ','))
  133.         *cp++ = 0;
  134.     buildpkt(pager, message);
  135.  
  136.     trys = 0;
  137. resend:
  138.     if (pgsend(packet))
  139.         return(1);
  140.     pgrecv("^C\r\n", 10);    /* ^C\r\n */
  141.  
  142.     /* Wait for ACK, NAK, EOT or Ready(?) */
  143.     if ((i = pgrecv("\r", 10)) <= 0) {
  144.         fprintf(stderr, "page send no reply\n");
  145.         goto done;
  146.     }
  147.     switch(inbuf[i-2]) {
  148.     default:    fprintf(stderr, "page send reply error\n");
  149.             goto done;
  150.     case ACK:    ret = 0; goto sent;
  151.     case NAK:    if (trys++ < 4) goto resend; else goto done;
  152.     case RS:    fprintf(stderr, "page send got RS\n"); goto done;
  153.     case ESC:
  154.         switch(inbuf[1]) {
  155.         case EOT:    goto done;
  156.         case '[':    if(inbuf[2] == 'p') { ret = 1; goto sent; }
  157.         default:    fprintf(stderr, "got unknown ESC code\n");
  158.                 goto done;
  159.         }
  160.     }
  161. sent:
  162.     if(cp) {
  163.         pager = cp;
  164.         goto next_pager;
  165.     }
  166.  
  167. done:
  168.     /* Logout: EOT CR */
  169.     if (pgsend("\004\r"))
  170.         return(ret);
  171.     pgrecv("\r", 3);
  172.     fputs(ret ? "[Error in delivery]\n" : inbuf, stderr);
  173.     pgrecv("\r", 3);
  174.     return(ret);
  175. }
  176.  
  177. pgsend(cp)
  178. char *cp;
  179. {
  180.     int    i, len = strlen(cp);
  181.  
  182.     nap(40);
  183.     if(vflag)
  184.         fprintf(stderr, "sending: ");
  185.     for (i = 0; i < len; i++) {
  186.         nap(75);
  187.         if(vflag)
  188.             show(cp, 1, stderr);
  189.         if (write(FD, cp, 1) != 1) {
  190.             fprintf(stderr, "pgsend error\n");
  191.             return(-1);
  192.         }
  193.         cp++;
  194.     }
  195.     if(vflag)
  196.         fputc('\n', stderr);
  197.     return(0);
  198. }
  199.  
  200. pgrecv(want, secs)
  201. char *want;
  202. int secs;
  203. {
  204.     jmp_buf savebuf;
  205.     int i, size;
  206.     char *cp, *endcp;
  207.     
  208.     bcopy(jmpbuf, savebuf, sizeof(jmpbuf));
  209.     if (setjmp(jmpbuf)) {
  210.         if(vflag)
  211.             fprintf(stderr, "\nrecv: timeout\n");
  212.         bcopy(savebuf, jmpbuf, sizeof(jmpbuf));
  213.         return(0);
  214.     }
  215.     signal(SIGALRM, recvtimeout);
  216.     alarm(secs);
  217.  
  218.     size = strlen(want);
  219.     if(vflag) {
  220.         fprintf(stderr, "recv (want ");
  221.         show(want, size, stderr);
  222.         fprintf(stderr, "/%d): ", size);
  223.     }
  224.     i = size-1;
  225.  
  226.     cp = inbuf; endcp = inbuf+sizeof(inbuf)-1;
  227.     *cp = 0;
  228.     mbuf[0] = 0;
  229.     while (strncmp(mbuf, want, size) != 0 && cp < endcp) {
  230.         bcopy(mbuf+1, mbuf, size);
  231.         if (read(FD, &mbuf[i], 1) != 1)
  232.             goto readerror;
  233.         mbuf[i] &= 0177;
  234.         *cp++ = mbuf[i];
  235.         *cp = 0;
  236.         if(vflag)
  237.             show(&mbuf[i], 1, stderr);
  238.     }
  239.     alarm(0);
  240.     bcopy(savebuf, jmpbuf, sizeof(jmpbuf));
  241.     if (vflag)
  242.         fputs(" -- got it\n", stderr);
  243.     return(cp - inbuf);
  244. readerror:
  245.     alarm(0);
  246.     bcopy(savebuf, jmpbuf, sizeof(jmpbuf));
  247.     return(-1);
  248. }
  249.  
  250. buildpkt(pager, message)
  251. char *pager, *message;
  252. {
  253.     char    *cp = &packet[0];
  254.     int    sum;
  255.  
  256.     *cp++ = STX;
  257.     sum = STX;
  258.  
  259.     cp = addstr(pager, &sum, cp);
  260.     cp = addstr(message, &sum, cp);
  261.  
  262.     *cp++ = ETX;
  263.     sum += ETX;
  264.     *cp++ = '0' + ((sum>>8)&0xf);
  265.     *cp++ = '0' + ((sum>>4)&0xf);
  266.     *cp++ = '0' + (sum&0xf);
  267.     *cp++ = '\r';
  268.     *cp = 0;
  269. }
  270.  
  271. static char *
  272. addstr(s, sump, cp)
  273. char *s, *cp;
  274. int *sump;
  275. {
  276.     char c;
  277.     int sum = *sump;
  278.  
  279.     while(c = *s++) {
  280.         *cp = (isprint(c) ? c : '?');
  281.         sum += *cp;
  282.         cp++;
  283.     }
  284.     *cp++ = '\r';
  285.     sum += '\r';
  286.  
  287.     *sump = sum;
  288.     return(cp);
  289. }
  290.